from rest_framework import serializers

from drfstudy.models import Student, Classes


#针对已有模型类的时候(相同的代码，变量名，约束)，可以继承ModelSerializer
#StudentSerializer继承>ModelSerializer含有>serializers功能
class StudentSerializer(serializers.ModelSerializer):
    #新增自定义属性值 classes_name
    #班级classes名称来自班级模型 student.classes.name
    #序列化 响应到客户端的时候 班级的名称    只读状态显示出来， 显示的内容
    class_name = serializers.CharField(source='classes.name',read_only=True) #不添加read_only=True classes班级变为可操作项

    class Meta:
        model = Student  # 指定序列化模型
        #fields = '__all__'  # 展示所有
        exclude = ["is_delete"] #过滤掉逻辑删除

        #简单校验规则
        extra_kwargs = {
            # "age":{"min_value":18,"max_value":None}, #设置最小年龄最大年龄校验
            "classes":{"write_only":True} #12行显示classes.name只读，不需要显示calsses.id。反序列化时把classes 变为只写
        }


    #校验
    #学生名里面带drf
    #属性级别校验（某一个字段的额外校验）
    # def validate_name(self,value):  #value代表客户端传入的name字段数据
    #     if "drf" not in value:
    #         raise serializers.ValidationError("用户名必须带有drf")
    #     return value

    #多个字段校验/对象级别校验
    #attrs 客户端传入的所有数据{"key":"value"}
    def validate(self, attrs):
        # 判断drf 不在获取的name数据当中.不论大小写lower()——避免传入name名有大小写
        if "drf" not in attrs.get("name").lower():
            raise serializers.ValidationError("用户名必须带有drf")

        if 18 > attrs.get("age"):
            raise serializers.ValidationError("禁止未成年使用")
        return attrs
# 展示过滤的数据，StudentSerializerSimple是展示过滤数据/与15行校验规则对象都是Student。
class StudentSerializerSimple(serializers.ModelSerializer):
    class Meta:
        model = Student
        exclude=["is_delete","create_time","update_time","classes_id"]


#========================================================================上部分为以下简写
#学生模型的序列化器         #父类Serializer里面没有save保存方法
# 父类Serializer里面的instance判断是否为None ，instance为空时create创建，不为空update添加
# class StudentSerializer(serializers.Serializer):
#
#     # #id在表自动生成，根据情况设置，可加可不加,label=备注信息
#     id = serializers.IntegerField(read_only=True,label='ID')
#     name = serializers.CharField(max_length=20,label='姓名')
#     # required=False 校验时允许为空
#     age = serializers.IntegerField(required=False,label='年龄')
#     sex = serializers.IntegerField(required=False,label='性别')
#     create_time = serializers.DateTimeField(required=False,label='创建时间')
#     update_time = serializers.DateTimeField(required=False,label='修改时间')
#     #                default=False 没有传值时，默认为False
#     is_delete = serializers.BooleanField(required=False,label='逻辑删除',default=False)
#
#===================================================================================views视图77行省略简写以下代码
#     #重写create方法 保存数据
#     # validated_data 保存的是前端传来Studentserializer转python格式的数据(键值对形式)
#     def create(self, validated_data):
#         #**{"key":"value"}  函数拆包获取数据
#         return Student.objects.create(**validated_data)
#
#     def update(self, instance, validated_data):
#         #instance 拿到原来的数据
#         #validated_data 拿到通过serializer转成的python格式新数据
#         #通过instance得到name键=拿到的数据如果获得('name值'就修改，没有就保持原来的name值)
#         instance.name = validated_data.get('name', instance.name)
#         instance.age = validated_data.get('age', instance.age)
#         instance.sex = validated_data.get('sex', instance.sex)
#         instance.save()#保存数据
#         return instance #返回修改后的数据


class ClassesSerializer(serializers.ModelSerializer):

    #序列化器套序列化器
    #班级表展示学生信息 一对多 classes.student_set 关系=》 StudentSerializer
    #管理器名       serializers操作   多条学生信息    ↓序列化时只能查看学生信息不能修改
    student_set = StudentSerializer(many=True, read_only=True)



    class Meta:
        model = Classes #指定序列化模型
        exclude = ["is_delete"] #指定不映射字段。响应前端json数据时不显示

